package com.campus.help.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.help.common.Result;
import com.campus.help.dto.LaborStats;
import com.campus.help.entity.Labor;
import com.campus.help.vo.LaborVO;
import com.campus.help.entity.LaborApplication;
import com.campus.help.service.LaborService;
import com.campus.help.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 劳务服务控制器
 *
 * @author campus-help
 * @since 2025-09-18
 */
@Slf4j
@RestController
@RequestMapping("/labor")
public class LaborController {

    @Autowired
    private LaborService laborService;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private com.campus.help.mapper.StudentMapper studentMapper;

    @Autowired
    private com.campus.help.service.WeChatSecurityService weChatSecurityService;

    /**
     * 获取劳务列表（包含类型信息）
     * 支持未登录用户访问（返回所有学校的劳务）
     */
    @GetMapping("/list")
    public Result<Page<LaborVO>> getLaborList(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long typeId,
            @RequestParam(required = false) String location,
            @RequestParam(required = false) String workType,
            @RequestParam(required = false) Boolean urgent,
            @RequestParam(required = false) String date,
            HttpServletRequest request) {

        try {
            Long schoolId = null;
            Long studentId = null;
            
            // 尝试从token中获取学校ID，如果失败则返回所有学校的劳务
            try {
                String token = getTokenFromRequest(request);
                if (token != null && !token.isEmpty()) {
                    studentId = jwtUtils.getStudentIdFromToken(token);
                    schoolId = getSchoolIdByStudentId(studentId);
                }
            } catch (Exception e) {
                // 未登录或token无效，schoolId保持为null
                log.info("未登录用户访问劳务列表接口");
            }

            log.info("获取劳务列表 - studentId: {}, schoolId: {}, page: {}, size: {}", studentId, schoolId, page, size);

            Page<LaborVO> laborList = laborService.getLaborListWithType(page, size, keyword, typeId, location, workType, urgent, date, schoolId);
            return Result.success(laborList);
        } catch (Exception e) {
            log.error("获取劳务列表失败", e);
            return Result.error("获取劳务列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取劳务详情
     */
    @GetMapping("/detail/{id}")
    public Result<com.campus.help.vo.LaborDetailVO> getLaborDetail(@PathVariable Long id) {
        try {
            com.campus.help.vo.LaborDetailVO laborDetail = laborService.getLaborDetailWithPublisher(id);
            if (laborDetail == null) {
                return Result.error("劳务不存在");
            }

            // 增加浏览次数
            laborService.incrementViewCount(id);

            return Result.success(laborDetail);
        } catch (Exception e) {
            log.error("获取劳务详情失败", e);
            return Result.error("获取劳务详情失败: " + e.getMessage());
        }
    }

    /**
     * 发布劳务
     */
    @PostMapping("/publish")
    public Result<Labor> publishLabor(@RequestBody Labor labor, HttpServletRequest request) {
        try {
            // 从token中获取发布者ID和学校ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);
            Long schoolId = getSchoolIdByStudentId(publisherId);

            if (schoolId == null) {
                return Result.error("请先选择所在学校");
            }

            log.info("收到发布劳务请求: publisherId={}, schoolId={}, jobTitle={}, typeId={}", publisherId, schoolId, labor.getJobTitle(), labor.getTypeId());

            // 内容安全检测
            boolean isSafe = weChatSecurityService.checkLaborContentSecurity(
                    labor.getJobTitle(), 
                    labor.getDescription()
            );
            
            if (!isSafe) {
                log.warn("发布内容包含违规信息: publisherId={}, jobTitle={}", publisherId, labor.getJobTitle());
                return Result.error("发布失败：您发布的内容包含违规信息，请修改后重新发布");
            }

            Labor publishedLabor = laborService.publishLabor(labor, publisherId, schoolId);
            return Result.success("发布成功", publishedLabor);
        } catch (Exception e) {
            log.error("发布劳务失败", e);
            return Result.error("发布劳务失败: " + e.getMessage());
        }
    }

    /**
     * 更新劳务信息
     */
    @PutMapping("/update")
    public Result<Labor> updateLabor(@RequestBody Labor labor, HttpServletRequest request) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            // 内容安全检测
            boolean isSafe = weChatSecurityService.checkLaborContentSecurity(
                    labor.getJobTitle(), 
                    labor.getDescription()
            );
            
            if (!isSafe) {
                log.warn("更新内容包含违规信息: publisherId={}, jobTitle={}", publisherId, labor.getJobTitle());
                return Result.error("更新失败：您发布的内容包含违规信息，请修改后重新提交");
            }

            Labor updatedLabor = laborService.updateLabor(labor, publisherId);
            return Result.success("更新成功", updatedLabor);
        } catch (Exception e) {
            log.error("更新劳务失败", e);
            return Result.error("更新劳务失败: " + e.getMessage());
        }
    }

    /**
     * 关闭劳务
     */
    @PostMapping("/close/{id}")
    public Result<String> closeLabor(@PathVariable Long id, HttpServletRequest request) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            boolean success = laborService.closeLabor(id, publisherId);
            if (success) {
                return Result.success("关闭成功");
            } else {
                return Result.error("关闭失败");
            }
        } catch (Exception e) {
            log.error("关闭劳务失败", e);
            return Result.error("关闭劳务失败: " + e.getMessage());
        }
    }

    /**
     * 申请劳务
     */
    @PostMapping("/apply")
    public Result<LaborApplication> applyLabor(@RequestBody ApplyLaborRequest request, HttpServletRequest httpRequest) {
        try {
            // 从token中获取申请者ID
            String token = getTokenFromRequest(httpRequest);
            Long applicantId = jwtUtils.getStudentIdFromToken(token);

            LaborApplication application = laborService.applyLabor(
                    request.getLaborId(),
                    applicantId,
                    request.getApplicationNote()
            );

            return Result.success("申请成功", application);
        } catch (Exception e) {
            log.error("申请劳务失败", e);
            return Result.error("申请劳务失败: " + e.getMessage());
        }
    }

    /**
     * 获取劳务申请列表
     */
    @GetMapping("/applications/{laborId}")
    public Result<java.util.List<com.campus.help.vo.LaborApplicationVO>> getLaborApplications(@PathVariable Long laborId, HttpServletRequest request) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            java.util.List<com.campus.help.vo.LaborApplicationVO> applications = laborService.getLaborApplications(laborId, publisherId);
            return Result.success(applications);
        } catch (Exception e) {
            log.error("获取申请列表失败", e);
            return Result.error("获取申请列表失败: " + e.getMessage());
        }
    }

    /**
     * 分页获取劳务申请列表
     */
    @GetMapping("/applications/{laborId}/page")
    public Result<com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.campus.help.vo.LaborApplicationVO>> getLaborApplicationsPage(
            @PathVariable Long laborId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            HttpServletRequest request) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.campus.help.vo.LaborApplicationVO> applications =
                    laborService.getLaborApplicationsPage(laborId, publisherId, page, size);
            return Result.success(applications);
        } catch (Exception e) {
            log.error("获取申请列表失败", e);
            return Result.error("获取申请列表失败: " + e.getMessage());
        }
    }

    /**
     * 审核劳务申请
     */
    @PostMapping("/review")
    public Result<String> reviewApplication(@RequestBody ReviewApplicationRequest request, HttpServletRequest httpRequest) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(httpRequest);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            boolean success = laborService.reviewApplication(
                    request.getApplicationId(),
                    request.getStatus(),
                    request.getReviewNote(),
                    publisherId
            );

            if (success) {
                return Result.success("审核成功");
            } else {
                return Result.error("审核失败");
            }
        } catch (Exception e) {
            log.error("审核申请失败", e);
            return Result.error("审核申请失败: " + e.getMessage());
        }
    }

    /**
     * 完成劳务
     */
    @PostMapping("/complete")
    public Result<String> completeLabor(@RequestBody CompleteLaborRequest request, HttpServletRequest httpRequest) {
        try {
            // 从token中获取用户ID
            String token = getTokenFromRequest(httpRequest);
            Long userId = jwtUtils.getStudentIdFromToken(token);

            boolean success = laborService.completeLabor(request.getApplicationId(), request.getCompleteNote(), userId);

            if (success) {
                return Result.success("完成成功");
            } else {
                return Result.error("完成失败");
            }
        } catch (Exception e) {
            log.error("完成劳务失败", e);
            return Result.error("完成劳务失败: " + e.getMessage());
        }
    }

    /**
     * 获取我发布的劳务列表
     */
    @GetMapping("/my-published")
    public Result<Page<Labor>> getMyPublishedLabors(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            HttpServletRequest request) {
        try {
            // 从token中获取发布者ID
            String token = getTokenFromRequest(request);
            Long publisherId = jwtUtils.getStudentIdFromToken(token);

            Page<Labor> laborList = laborService.getMyPublishedLabors(publisherId, page, size);
            return Result.success(laborList);
        } catch (Exception e) {
            log.error("获取我发布的劳务失败", e);
            return Result.error("获取我发布的劳务失败: " + e.getMessage());
        }
    }

    /**
     * 获取我申请的劳务列表
     */
    @GetMapping("/my-applications")
    public Result<Page<LaborApplication>> getMyLaborApplications(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            HttpServletRequest request) {
        try {
            // 从token中获取申请者ID
            String token = getTokenFromRequest(request);
            Long applicantId = jwtUtils.getStudentIdFromToken(token);

            Page<LaborApplication> applications = laborService.getMyLaborApplications(applicantId, page, size);
            return Result.success(applications);
        } catch (Exception e) {
            log.error("获取我申请的劳务失败", e);
            return Result.error("获取我申请的劳务失败: " + e.getMessage());
        }
    }

    /**
     * 获取热门劳务服务（按浏览次数排序）
     * 支持未登录用户访问（返回所有学校的热门劳务）
     */
    @GetMapping("/hot")
    public Result<List<Labor>> getHotLabors(
            @RequestParam(defaultValue = "10") int limit,
            HttpServletRequest request) {
        try {
            Long schoolId = null;
            Long studentId = null;
            
            // 尝试从token中获取学校ID，如果失败则返回所有学校的热门劳务
            try {
                String token = getTokenFromRequest(request);
                if (token != null && !token.isEmpty()) {
                    studentId = jwtUtils.getStudentIdFromToken(token);
                    schoolId = getSchoolIdByStudentId(studentId);
                }
            } catch (Exception e) {
                // 未登录或token无效，schoolId保持为null
                log.info("未登录用户访问热门劳务接口");
            }

            log.info("获取热门劳务 - studentId: {}, schoolId: {}, limit: {}", studentId, schoolId, limit);

            List<Labor> hotLabors = laborService.getHotLabors(limit, schoolId);
            return Result.success(hotLabors);
        } catch (Exception e) {
            log.error("获取热门劳务失败", e);
            return Result.error("获取热门劳务失败: " + e.getMessage());
        }
    }

    /**
     * 获取劳务统计信息
     */
    @GetMapping("/stats")
    public Result<LaborStats> getLaborStats() {
        try {
            LaborStats stats = laborService.getLaborStats();
            return Result.success(stats);
        } catch (Exception e) {
            log.error("获取劳务统计失败", e);
            return Result.error("获取劳务统计失败: " + e.getMessage());
        }
    }

    /**
     * 从请求中获取token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        if (authorization != null && authorization.startsWith("Bearer ")) {
            return authorization.substring(7);
        }
        throw new RuntimeException("Token不能为空");
    }

    /**
     * 根据学生ID获取学校ID
     */
    private Long getSchoolIdByStudentId(Long studentId) {
        try {
            com.campus.help.entity.Student student = studentMapper.selectById(studentId);
            if (student == null) {
                throw new RuntimeException("学生不存在");
            }
            return student.getSchoolId();
        } catch (Exception e) {
            log.error("获取学生学校ID失败: studentId={}", studentId, e);
            throw new RuntimeException("获取学生学校ID失败: " + e.getMessage());
        }
    }

    /**
     * 申请劳务请求类
     */
    public static class ApplyLaborRequest {
        private Long laborId;
        private String applicationNote;

        public Long getLaborId() {
            return laborId;
        }

        public void setLaborId(Long laborId) {
            this.laborId = laborId;
        }

        public String getApplicationNote() {
            return applicationNote;
        }

        public void setApplicationNote(String applicationNote) {
            this.applicationNote = applicationNote;
        }
    }

    /**
     * 审核申请请求类
     */
    public static class ReviewApplicationRequest {
        private Long applicationId;
        private String status;
        private String reviewNote;

        public Long getApplicationId() {
            return applicationId;
        }

        public void setApplicationId(Long applicationId) {
            this.applicationId = applicationId;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getReviewNote() {
            return reviewNote;
        }

        public void setReviewNote(String reviewNote) {
            this.reviewNote = reviewNote;
        }
    }

    /**
     * 完成劳务请求类
     */
    public static class CompleteLaborRequest {
        private Long applicationId;
        private String completeNote;

        public Long getApplicationId() {
            return applicationId;
        }

        public void setApplicationId(Long applicationId) {
            this.applicationId = applicationId;
        }

        public String getCompleteNote() {
            return completeNote;
        }

        public void setCompleteNote(String completeNote) {
            this.completeNote = completeNote;
        }
    }
}
